package JasPerl::CGI::Request;

use 5.010;
use strict;
use warnings;

use parent qw(JasPerl::Request);

use I18N::LangTags::Detect;
use JasPerl::Util::Enumeration;
use JasPerl::Util::Locale;
use JasPerl::Util::Cookie;

use CGI qw(-oldstyle_urls);
use CGI::Cookie;

sub new {
    my ($class, $cgi) = @_;
    my $self = bless { cgi => $cgi || CGI->new() }, $class;

    my $data = $cgi->param('POSTDATA') // $cgi->param('PUTDATA');
    if (defined $data) {
        open(my $fh, '<', \$data) or die "open: $!";
        $self->{reader} = $fh;
    }

    return $self;
}

sub get_attribute_names {
    return JasPerl::Util::Enumeration->from_list(keys %{$_[0]->{attrs}});
}

sub get_attribute {
    return $_[0]->{attrs}->{$_[1]};
}

sub set_attribute {
    if (defined $_[2]) {
        $_[0]->{attrs}->{$_[1]} = $_[2];
    } else {
        delete $_[0]->{attrs}->{$_[1]};
    }
}

sub remove_attribute {
    delete $_[0]->{attrs}->{$_[1]};
}

# java.lang.String 	getContentType()
sub get_content_type {
    return $_[0]->{cgi}->content_type();
}

# int 	getContentLength()
sub get_content_length {
    # not provided by CGI.pm
    return exists $ENV{'CONTENT_LENGTH'} ? $ENV{'CONTENT_LENGTH'} : -1;
}

# java.lang.String 	getCharacterEncoding()
sub get_character_encoding {
}

# void 	setCharacterEncoding(java.lang.String enc)
sub set_character_encoding {
}

# java.util.Enumeration<java.util.Locale> 	getLocales()
sub get_locales {
    my $self = shift;

    # FIXME: use accept-language header directly?
    my @locales = map { JasPerl::Util::Locale->from($_) } I18N::LangTags::Detect::detect;

    if (@locales) {
        return JasPerl::Util::Enumeration->from_list(@locales);
    } else {
        return $self->SUPER::get_locales();
    }
}

# java.lang.String 	getParameter(java.lang.String name)
sub get_parameter {
    return $_[0]->{cgi}->param($_[1]);
}

# java.util.Enumeration<java.lang.String> 	getParameterNames()
sub get_parameter_names {
    return JasPerl::Util::Enumeration->from_list($_[0]->{cgi}->param());
}

# java.lang.String[] 	getParameterValues(java.lang.String name)
sub get_parameter_values {
    return $_[0]->{cgi}->param_fetch($_[1]);
}

# java.lang.String 	getScheme()
sub get_scheme {
    return $_[0]->{cgi}->protocol();
}

# java.lang.String 	getProtocol()
sub get_protocol {
    return $_[0]->{cgi}->server_protocol();
}

# boolean 	isSecure()
sub is_secure {
    return uc($_[0]->{cgi}->https() || '') eq 'ON';
}

# java.lang.String 	getServerName()
sub get_server_name {
    return $_[0]->{cgi}->server_name();
}

# int 	getServerPort()
sub get_server_port {
    return $_[0]->{cgi}->server_port();
}

# java.lang.String 	getLocalAddr()
sub get_local_addr {
    # not provided by CGI.pm
    return exists $ENV{'SERVER_ADDR'} ? $ENV{'SERVER_ADDR'} : -1;
}

# java.lang.String 	getLocalName()
sub get_local_name {
    return $_[0]->get_server_name();
}

# int 	getLocalPort()
sub get_local_port {
    return $_[0]->get_server_port();
}

# java.lang.String 	getRemoteAddr()
sub get_remote_addr {
    return $_[0]->{cgi}->remote_addr();
}

# java.lang.String 	getRemoteHost()
sub get_remote_host {
    return $_[0]->{cgi}->remote_host();
}

# int 	getRemotePort()
sub get_remote_port {
    # not provided by CGI.pm
    return exists $ENV{'REMOTE_PORT'} ? $ENV{'REMOTE_PORT'} : -1;
}

# RequestDispatcher 	getRequestDispatcher(java.lang.String path)
sub get_request_dispatcher {
}

# Cookie[] 	getCookies()
sub get_cookies {
    my %cookies = CGI::Cookie->fetch();
    my @cookies = map { JasPerl::Util::Cookie->from($_) } values %cookies;
    return \@cookies;
}

# java.lang.String 	getHeader(java.lang.String name)
sub get_header {
    # FIXME: list/split multiple headers
    return $_[0]->{cgi}->http($_[1]);
}

# java.util.Enumeration<java.lang.String> 	getHeaders(java.lang.String name)
sub get_headers {
    # FIXME: list/split multiple headers
    return JasPerl::Util::Enumeration->from_list($_[0]->{cgi}->http($_[1]));
}

# java.util.Enumeration<java.lang.String> 	getHeaderNames()
sub get_header_names {
    my @headers = $_[0]->{cgi}->http();
    # FIXME: format headers
    s/^HTTP_// foreach @headers;
    return JasPerl::Util::Enumeration->from_list(@headers);
}

# java.lang.String 	getMethod()
sub get_method {
    return $_[0]->{cgi}->request_method();
}

# java.lang.String 	getPathInfo()
sub get_path_info {
    return $_[0]->{cgi}->path_info();
}

# java.lang.String 	getPathTranslated()
sub get_path_translated {
    return $_[0]->{cgi}->path_translated();
}

# java.lang.String 	getQueryString()
sub get_query_string {
    return $_[0]->{cgi}->query_string();
}

# java.lang.String 	getRemoteUser()
sub get_remote_user {
    return $_[0]->{cgi}->remote_user();
}

# java.lang.String 	getRequestURI()
sub get_request_uri {
    return $_[0]->{cgi}->url(-absolute => 1);
}

# java.lang.StringBuffer 	getRequestURL()
sub get_request_url {
    return $_[0]->{cgi}->url(-full => 1);
}
# java.io.BufferedReader 	getReader()
sub get_reader {
    return $_[0]->{reader} || $_[0]->SUPER::get_reader();
}

sub DESTROY {
    warn "DESTROY CGI REQUEST";
    $_[0]->{reader}->close() if $_[0]->{reader};
}

1;
